<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Ajax demo</title>
</head>

<body>

    <script>
        (function () {
            var xhr = null;
            if (window.XMLHttpRequest) {
                //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
                xhr = new XMLHttpRequest();
            } else {
                // IE6, IE5 浏览器执行代码
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
            // 只要readyState属性的值由一个值变为另一个值，都会触发一次readystatechange事件
            xhr.onreadystatechange = function () {
                if (xhr.status === 200 && xhr.readyState === 4) {
                    var res = xhr.responseText;
                    console.log("请求成功");
                } else {
                    console.log("请求失败");
                }
            }
            // 必须在open() 之前指定onreadystatechange事件处理程序才能确保浏览器兼容性
            // 三个参数 请求类型，请求地址，是否异步请求
            // 当您使用 async=false 时，请不要编写 onreadystatechange 函数 - 
            // 把  var res=xhr.responseText;代码放到 send() 语句后面即可：
            xhr.open("get/post", "url", false / true);

            // 要成功发送请求信息，必须在open方法调用之后send方法调用之前 调用setRequestHeader();
            xhr.setRequestHeader("myHeader", "myValue");

            // 发送的数据 有为data，无为null；
            xhr.send(data / null);
        })();
        !function () {
            // 使用get时查询字符串中的每个参数的名称和值都必须使用encodeURIComponent()进行编码，然后才能放到URL的末尾
            // 而且所有的名-值对都必须由和号（&）分隔

            //如下面例子
            var url = 'example.php';
            url = addURLParam(url, 'name1', 'value1');
            url = addURLParam(url, 'name2', 'value2');
            // url 通过编码后
            function addURLParam(url, name, value) {
                // 判断url是否已经有了参数（有问号表示已经有了参数） 有就往url后面加上一个 & ，没有加上 ? 
                url += url.indexOf('?') !== -1 ? '&' : '?';
                // 进行名-值对的编码
                url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
                return url;
            }
            xhr.open('get', url, true);

        }();
        (function () {
            // 使用XHR来模仿表单提交：首先将Content-type 头部信息设置为application/x-www-form-urlencoded,
            // 其次是是以适当的格式将表单中的数据进行序列号 
            xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            var form = document.getElementById('myForm');
            xhr.send(serialize(form));

            // XMLHttpRequest 2级 定义了FormData类型，为序列化表单以及创建与表单格式相同的数据（用于通过XHR传输）提供了便利
            var data = new FormData();
            data.append("name", "value");

            //通过向FormData构造函数中传入表单元素，就可以用表单元素数据先向其中填入键值对：
            var data = new FormData(document.forms[0]);
            xhr.send(data);
            // 使用FormData 的方便之处体现在不需要明确的指定xhr对象头部信息，
            // xhr对象能够自己识别传入的数据类型是FormData数据，并配置适当的头部信息
        })();

        (function () {
            // overrideMemeType()方法，用于重写XHR响应的MIME类型，因为返回响应的MIME类型决定了XHR对象如何处理它
            xhr.open('get', 'text.php', true);
            // 这个例子强迫XHR对象将响应当做XML而非纯文本来处理，
            // 调用overrideMemeType()必须在send方法之前，才能保证重写响应的MIME类型
            xhr.overrideMemeType('text/xml');
            xhr.send(null);
        })();

        (function () {
            // progress 事件 这个事件会在浏览器接受新数据期间周期性的触发，
            // onprogress 接受到一个event事件对象，其target指向XHR对象  
            // 而且包含额外三个属性 lengthComputable 表示进度信息是否可用的布尔值  
            // position 表示已经接收到的字节数 totalSize 表示根据Content-Length响应头部确定的预期字节数
            // 可以为用户创建一个进度指示器

            xhr.onprogress=function(event){
                if(event.lengthComputable){
                    console.log("接受到的数据百分比："+(event.position/event.totalSize)*100+'%');
                }
            }
            // 必须在open方法调用之前添加onprogress事件处理程序
            xhr.open('get','text.php',true);
            xhr.send(null);
            
        })();
    </script>
</body>

</html>